﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using CSharp.Libs.WPF;
using AutoKoC.Models;
using System.Windows.Input;
using System.Collections.ObjectModel;
using AutoKoC.ViewModels.ItemClasses;
using System.Collections;

namespace AutoKoC.ViewModels
{
    class AutoCresterViewModel : ViewModelBase
    {
        #region declarations
        private AppBase _AB = null;
        private MarchSender _MS = null;

        private ObservableCollection<SeedCityKnightItem> _ocKnights = new ObservableCollection<SeedCityKnightItem>();

        private RelayCommand _rcSendMarch = null;

        private Int32 _intDextinationX = 0;
        private Int32 _intDextinationY = 0;
        private Int32 _intCityID = 0;
        private Int32 _intKnightID = 0;
        private Int32 _intMilitiaman = 0;
        private Int32 _intScout = 0;
        private Int32 _intPikeman = 0;
        private Int32 _intSwordsman = 0;
        private Int32 _intArcher = 0;
        private Int32 _intHeavyCavalry = 0;
        private Int32 _intWaggon = 0;
        private Int32 _intBallista = 0;
        private String _strResult = "";
        #endregion



        #region constructor / terminator
        public AutoCresterViewModel(
            AppBase AB)
        {
            _AB = AB;
            _MS = new MarchSender(_AB);

            _MS.ResultStringReceived += new MarchSender.ResultStringReceivedEventHandler(_MS_ResultStringReceived);
            _AB.TM.KocServerChanged += new TrafficMonitor.KocServerChangedEventHandler(TM_KocServerChanged);
        }

        ~AutoCresterViewModel()
        {
            _ocKnights = null;

            if(_MS != null)
            {
                _MS.ResultStringReceived -= _MS_ResultStringReceived;
                
                _MS = null;
            }

            if(_AB != null)
            {

                if(_AB.TM != null)
                {
                    _AB.TM.KocServerChanged -= TM_KocServerChanged;
                }

                _AB = null;
            }
        }
        #endregion



        #region event handling
        void _MS_ResultStringReceived(object sender, ResultStringReceivedEventArgs ea)
        {
            _strResult = String.Concat(_strResult, ea.Result, Environment.NewLine);
            OnPropertyChanged("Result");
        }

        void TM_KocServerChanged(object sender)
        {
            OnPropertyChanged("Cities");
        }
        #endregion
        


        #region private functions
        /// <summary>_SendMarch</summary>
        /// <history>13.05.2011</history>
        private void _SendMarch()
        {
            try
            {
                //(508,471) Lv.8 Barb
                //10363 (CityID City1 Bocinity)
                //42856 (KnightID Bianca)

                _MS.Type = MarchSender.MarchTypes.Attack;
                _MS.CityID = _intCityID.ToString();
                _MS.KnightID = _intKnightID.ToString();
                _MS.XCoord = _intDextinationX.ToString();
                _MS.YCoord = _intDextinationY.ToString();

                _MS.AddTroopType(MarchSender.TroopType.Militiaman, _intMilitiaman);
                _MS.AddTroopType(MarchSender.TroopType.Scout, _intScout);
                _MS.AddTroopType(MarchSender.TroopType.Pikeman, _intPikeman);
                _MS.AddTroopType(MarchSender.TroopType.Swordsman, _intSwordsman);
                _MS.AddTroopType(MarchSender.TroopType.Archer, _intArcher);
                _MS.AddTroopType(MarchSender.TroopType.HeavyCavalry, _intHeavyCavalry);
                _MS.AddTroopType(MarchSender.TroopType.SupplyWaggon, _intWaggon);
                _MS.AddTroopType(MarchSender.TroopType.Ballista, _intBallista);

                _MS.ExecuteMarch(_AB.InternalUID);
            }
            catch (Exception ex)
            {
                _AB.EC.AddException(ex, this.ToString(), _AB.EC.Tools.GetCurrentMethodName());
            }
        }

        /// <summary>_GetKnightOfCity</summary>
        /// <history>14.05.2011</history>
        private void _GetKnightOfCity()
        {
            try
            {
                _ocKnights.Clear();

                if(_intCityID != 0)
                {
                    foreach(SeedCityItem SCI in _AB.BSVM.Cities)
                    {
                        if(SCI.CityID == _intCityID)
                        {
                            foreach(KeyValuePair<String, SeedCityKnightItem> KVP in SCI.Knights)
                            {
                                _ocKnights.Add(KVP.Value);
                            }

                            break;
                        }
                    }

                    _intKnightID = 0;

                    OnPropertyChanged("Knights");
                    OnPropertyChanged("KnightID");
                }
            }
            catch(Exception ex)
            {
                _AB.EC.AddException(ex, this.ToString(), _AB.EC.Tools.GetCurrentMethodName());
            }
        }
        #endregion



        #region interface
        #region properties
        public ObservableCollection<SeedCityItem> Cities
        {
            get
            {
                return _AB.BSVM.Cities;
            }
        }

        public ObservableCollection<SeedCityKnightItem> Knights
        {
            get
            {
                return _ocKnights;
            }
        }

        public Int32 DextinationX
        {
            get
            {
                return _intDextinationX;
            }
            set
            {
                _intDextinationX = value;
            }
        }

        public Int32 DextinationY
        {
            get
            {
                return _intDextinationY;
            }
            set
            {
                _intDextinationY = value;
            }
        }

        public Int32 CityID
        {
            get
            {
                return _intCityID;
            }
            set
            {
                _intCityID = value;
                _GetKnightOfCity();
                OnPropertyChanged("CityID");
            }
        }

        public Int32 KnightID
        {
            get
            {
                return _intKnightID;
            }
            set
            {
                _intKnightID = value;
                OnPropertyChanged("KnightID");
            }
        }

        public Int32 Militiaman
        {
            get
            {
                return _intMilitiaman;
            }
            set
            {
                _intMilitiaman = value;
            }
        }

        public Int32 Scout
        {
            get
            {
                return _intScout;
            }
            set
            {
                _intScout = value;
            }
        }

        public Int32 Pikeman
        {
            get
            {
                return _intPikeman;
            }
            set
            {
                _intPikeman = value;
            }
        }

        public Int32 Swordsman
        {
            get
            {
                return _intSwordsman;
            }
            set
            {
                _intSwordsman = value;
            }
        }

        public Int32 Archer
        {
            get
            {
                return _intArcher;
            }
            set
            {
                _intArcher = value;
            }
        }

        public Int32 HeavyCavalry
        {
            get
            {
                return _intHeavyCavalry;
            }
            set
            {
                _intHeavyCavalry = value;
            }
        }

        public Int32 Waggon
        {
            get
            {
                return _intWaggon;
            }
            set
            {
                _intWaggon = value;
            }
        }

        public Int32 Ballista
        {
            get
            {
                return _intBallista;
            }
            set
            {
                _intBallista = value;
            }
        }

        public String Result
        {
            get
            {
                return _strResult;
            }
        }

        public ICommand SendMarch
        {
            get
            {
                if (_rcSendMarch == null)
                {
                    _rcSendMarch = new RelayCommand(
                        param => this._SendMarch(),
                        param => this.CanSendMarch);
                }
                return _rcSendMarch;
            }
        }
        public Boolean CanSendMarch
        {
            get
            {
                return _MS.CanExecuteMarch;
            }
        }
        #endregion

        #region methods
        #endregion
        #endregion
    }
}
